﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;

namespace Example
{
	internal struct SimpleSpinLock
	{
		private Int32 m_ResourceInUse; // 0=false (default), 1=true
		public void Enter()
		{
			// Set the resource to in-use and if this thread
			// changed it from Free, then return
			while (Interlocked.Exchange(ref m_ResourceInUse, 1) != 0)
			{
				/* Black Magic goes here... */
			}
		}
		public void Leave()
		{
			// Mark the resource as Free
			Thread.VolatileWrite(ref m_ResourceInUse, 0);
		}
	}

	internal sealed class SimpleWaitLock : IDisposable
	{
		private AutoResetEvent m_ResourceFree = new AutoResetEvent(true); // Initially free
		public void Enter()
		{
			// Block efficiently in the kernel for the resource to be free, then return
			m_ResourceFree.WaitOne();
		}
		public void Leave()
		{
			m_ResourceFree.Set();// Mark the resource as Free
		}
		public void Dispose() { ((IDisposable)m_ResourceFree).Dispose(); }
	}

	class Program
	{
		public static void Main()
		{
			int i = 2;
			int j = 3;
			int r = ++i * 2 + 3 * j++;
			Console.WriteLine(r);
			Console.ReadKey();
		}
	}
}
